#include "..\\code\\dataStruct.h"
#include "..\\code\\common.h"

// 自动重合闸
extern void autoReclose(Device *device);
// 失灵保护
extern void failedRelay(Device *device);
// 三相不一致保护
extern void threePhaseUnMatch(Device *device);
// 单相重合闸
extern void singleReclose(Device* device, int phase);
// 三相重合闸
extern void threeReclose(Device* device);
// 信号综合控制
extern void breakerTripController(Device* device);


void breaker(Device *device) {

    // 将采样值存入瞬时值数组
    sample2inst(device);

    // 瞬时值滤波后存入并更新滤波后数组
    dataFilter(device);

    // 利用滤波后数据计算12通道相量, 存入phasor数组
    toPhasor(device);

    if (device->time < STABLE_TIME) {
        // 等待仿真进入稳定状态
        return;
    }

    // 自动重合闸
    autoReclose(device);

    // 失灵保护
    failedRelay(device);

    // 三相不一致保护
    threePhaseUnMatch(device);

    breakerTripController(device);

}

// 自动重合闸
void autoReclose(Device *device) {
    int phase = 0;
    // 自动重合闸部分
    if (device->breaker.singleRecloseEnable == 1 && device->breaker.threeRecloseEnable == 0) {
        // 单相重合闸
        for (phase = 0; phase < 3; phase++) {
            singleReclose(device, phase);
        }
    } else if (device->breaker.singleRecloseEnable == 0 && device->breaker.threeRecloseEnable == 1) {
        // 三相重合闸 检测到任意一相位置不对应后, 启动重合闸计时, 计时到达后, 三重同时发脉冲
        threeReclose(device);
    } else if (device->breaker.singleRecloseEnable == 1 && device->breaker.threeRecloseEnable == 1) {
        // 控制字设置错误, 不启动重合闸
        writeErrorLog(device, "重合闸重合方式整定错误");
    } else if (device->breaker.singleRecloseEnable == 0 && device->breaker.threeRecloseEnable == 0) {
        writeErrorLog(device, "停用重合闸");
    }
}


// 单相重合闸
void singleReclose(Device* device, int phase) {
    if (device->breaker.singleRecloseEnable == 0) return;
    // 重合闸闭锁, 或重合闸已经动作, 不再进入判断
    if (device->breaker.recloseShutFlag[phase] == 1 || device->breaker.recloseTripFlag[phase] == 1) return;

    if (device->breaker.recloseStartFlag[phase] == 0) {
        // 重合闸启动判定, 分闸状态
        if (device->brkStatus[0][phase] == 0) {
            writeLogWithPhase(device, "断路器%c相重合闸启动", phase);
            device->breaker.recloseStartFlag[phase] = 1;
            device->breaker.recloseStartTime[phase] = device->time;
        }
    } else if (device->breaker.recloseStartFlag[phase] == 1) {
        // 重合闸已经启动, 根据重合闸延时进行动作判定
        if (device->time > device->breaker.recloseStartTime[phase] + device->breaker.singleRecloseTimeSet) {
            device->breaker.recloseTripFlag[phase] = 1;
            // 闭锁重合闸
            device->breaker.recloseShutFlag[phase] = 1;
            writeLogWithPhase(device, "断路器%c相重合闸动作", phase);
        }
    }

}


// 三相重合闸, 任意一相分闸之后, 三相跳闸; 到达整定时间后三重
void threeReclose(Device* device) {
    int phase = 0, k = 0;
    if (device->breaker.threeRecloseEnable == 0) return;
    // 单相跳闸后跳三相
    for (phase = 0; phase < 3; phase++) {
        if (device->brkStatus[0][phase] == 0 && device->brkStatus[1][phase] == 1) {
            // 将其他相也跳闸
            device->breaker.breaker3JumpTripFlag = 1;
            writeLogWithPhase(device, "%c相跳闸后同时跳开三相", phase);
            break;
        }
    }
    // 三相重合闸闭锁或已经动作, 不再判断
    if (device->breaker.reclose3ShutFlag == 1 || device->breaker.reclose3TripFlag == 1) return;

    if (device->breaker.reclose3StartFlag == 0) {
        // 重合闸启动判定, 任何一相处于分闸状态
        for (phase = 0; phase < 3; phase++) {
            if (device->brkStatus[0][phase] == 0 && device->brkStatus[1][phase] == 1) {
                writeLog(device, "断路器三相重合闸启动");
                device->breaker.reclose3StartFlag = 1;
                device->breaker.reclose3StartTime = device->time;
                break;
            }
        }
    } else if (device->breaker.reclose3StartFlag == 1) {
        if (device->time > device->breaker.reclose3StartTime + device->breaker.threeRecloseTimeSet) {
            device->breaker.reclose3TripFlag = 1;
            // 闭锁重合闸
            device->breaker.reclose3ShutFlag = 1;
            writeLog(device, "断路器三相重合闸动作");
        }
    }
}

// 失灵保护
void failedRelay(Device *device) {
    if (device->breaker.failedRelayEnable == 0) return;
    int phase = 0, k = 0;
    Phasor I0;

    // 记录保护跳闸时刻
    for (phase = 0; phase < 3; phase++) {
        if (device->breaker.lineTripSignal[0][phase] == 1 && device->breaker.lineTripSignal[1][phase] == 0) {
            if (notYetWithPhase(device, "监测到%c相跳闸信号", phase)) {
                // 前一点没有跳闸信号, 而当前有跳闸信号1
                device->breaker.lineRelayTripFlag[phase] = 1;
                device->breaker.lineRelayTripTime[phase] = device->time;
                writeLogWithPhase(device, "失灵保护检测到线路保护%c相跳闸", phase);
            }
        }
    }

    // 如果跳闸后超过失灵保护整定时间且故障仍然存在, 失灵保护动作
    for (phase = 0; phase < 3; phase++) {
        if (device->breaker.failedRelayTripFlag == 1) break;
        // 超过失灵保护动作时间
        if (device->breaker.lineRelayTripFlag[phase] == 1 && device->time > device->breaker.lineRelayTripTime[phase] + device->breaker.failedRelayTimeSet) {
            // 故障仍然存在, 使用零序电流判断
            I0 = phasorAdd(device->phasor[3], phasorAdd(device->phasor[4], device->phasor[5]));
            if (phasorAbs(I0) > device->breaker.failedRelayZeroCurrentSet) {
                device->breaker.failedRelayTripFlag = 1;
                // 闭锁重合闸
                for (k = 0; k < 3; k++) {
                    device->breaker.recloseShutFlag[k] = 1;
                }
                device->breaker.reclose3ShutFlag = 1;
                writeLog(device, "断路器失灵保护动作");
                break;
            }
        }
    }
}
// 三相不一致保护
void threePhaseUnMatch(Device *device) {
    int k = 0;
    if (device->breaker.phaseUnMatchEnable == 0) return;

    if (device->breaker.phaseUnMatchStartFlag == 0) {
        // 三相或运算为1, 与运算为0, 说明有在运行的相和停运的相, 即三相不一致
        int brkA = device->brkStatus[0][0];
        int brkB = device->brkStatus[0][1];
        int brkC = device->brkStatus[0][2];
        if (((brkA || brkB || brkC) == 1) && ((brkA && brkB && brkC) == 0)) {
            device->breaker.phaseUnMatchStartFlag = 1;
            device->breaker.phaseUnMatchStartTime = device->time;
            writeLog(device, "断路器三相不一致保护启动");
        }
    }

    if (device->breaker.phaseUnMatchStartFlag == 1 && device->breaker.phaseUnMatchTripFlag == 0) {
        if (device->time > device->breaker.phaseUnMatchStartTime + device->breaker.phaseUnMatchTimeSet) {
            // 三相或运算为1, 与运算为0, 说明有在运行的相和停运的相, 即三相不一致
            int brkA = device->brkStatus[0][0];
            int brkB = device->brkStatus[0][1];
            int brkC = device->brkStatus[0][2];
            if (((brkA || brkB || brkC) == 1) && ((brkA && brkB && brkC) == 0)) {
                // 如果仍然不一致, 则跳闸
                device->breaker.phaseUnMatchTripFlag = 1;
                writeLog(device, "断路器三相不一致保护动作");
                // 闭锁重合闸
                for (k = 0; k < 3; k++) {
                    device->breaker.recloseShutFlag[k] = 1;
                }
                device->breaker.reclose3ShutFlag = 1;
            }
        }
    }

}

void breakerTripController(Device* device) {
    int phase = 0;
    for (phase = 0; phase < 3; phase++) {
        if (device->breaker.recloseTripFlag[phase] == 1) {
            writeLogWithPhase(device, "断路器%c相合闸动作信号出口", phase);
            device->breaker.breakerOnTripFlag[phase] = 1;
        }
    }

    if (device->breaker.breaker3JumpTripFlag == 1 || device->breaker.failedRelayTripFlag == 1 || device->breaker.phaseUnMatchTripFlag == 1) {
        for (phase = 0; phase < 3; phase++) {
            device->breaker.breakerOffTripFlag[phase] = 1;
        }
        writeLog(device, "断路器三相跳闸动作信号出口");
        device->breaker.breaker3JumpTripFlag = 0;
        device->breaker.phaseUnMatchTripFlag = 0;
    } else {
        for (phase = 0; phase < 3; phase++) {
            device->breaker.breakerOffTripFlag[phase] = 0;
        }
    }

    if (device->breaker.externalTripEnable == 1) {
        // 外部信号跳闸
        for (phase = 0; phase < 3; phase++) {
            if (device->breaker.externalTripSignal[0][phase] == 1 && device->breaker.externalTripSignal[1][phase] == 0) {
                device->breaker.breakerOffTripFlag[phase] = 1;
                writeLogWithPhase(device, "%c相外部信号跳闸动作出口", phase);
            }
        }
    }

    if (device->breaker.reclose3TripFlag == 1) {
        for (phase = 0; phase < 3; phase++) {
            device->breaker.breakerOnTripFlag[phase] = 1;
        }
        writeLog(device, "断路器三相合闸动作信号出口");
    }
}

// 2020